package com.wewins.fota.sys.service;

import com.wewins.fota.bean.bo.filter.PkgFilterCond;
import com.wewins.fota.bean.bo.filter.PlanFilterCond;
import com.wewins.fota.bean.dto.PageReq;
import com.wewins.fota.bean.dto.PageRst;
import com.wewins.fota.bean.po.PkgVersion;
import com.wewins.fota.bean.po.UpdatePlan;
import com.wewins.fota.service.PkgVersionService;
import com.wewins.fota.service.PlanService;
import com.wewins.fota.service.RedisCacheService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Slf4j
@Service
public class FotaCacheManager {

    private final PlanService planService;

    private final PkgVersionService pkgVersionService;

    private final RedisCacheService redisCacheService;

    @Autowired
    public FotaCacheManager(PlanService planService, PkgVersionService pkgVersionService, RedisCacheService redisCacheService) {
        this.planService = planService;
        this.pkgVersionService = pkgVersionService;
        this.redisCacheService = redisCacheService;
    }

    /**
     * 重建缓存
     */
    @Transactional(rollbackFor = Exception.class)
    public void rebuildCache() {
        long start = System.currentTimeMillis();
        log.info("start to rebuild fota redis cache.");
        try {
            redisCacheService.clearAllCache();
            this.cachePkg();
            this.cachePlan();
        } catch (Exception e) {
            log.error("failed to create redis cache:", e);
            redisCacheService.clearAllCache();
            throw e;
        }
        log.info("cache rebuild finish, cost:" + (System.currentTimeMillis() - start) + " ms!!");
    }

    private void cachePlan() {
        log.info("start to cache update plan info at redis.");
        PageReq<PlanFilterCond> pageReq = PageReq.<PlanFilterCond>builder().pageNum(1).pageSize(100).build();
        PageRst<UpdatePlan> planPage;
        do {
            planPage = planService.queryAll(pageReq);
            planPage.getData().forEach(redisCacheService::cacheOnePlan);
            pageReq.setPageNum(pageReq.getPageNum() + 1);
        } while (pageReq.getPageNum() <= planPage.getTotalPages());
        log.info("cache update plan info finish!!!");
    }

    private void cachePkg() {
        log.info("start to cache package info at redis.");
        PageReq<PkgFilterCond> pageReq = PageReq.<PkgFilterCond>builder().pageNum(1).pageSize(100).build();
        PageRst<PkgVersion> pkgPage;
        do {
            pkgPage = pkgVersionService.queryAll(pageReq);
            pkgPage.getData().forEach(redisCacheService::cacheOnePkg);
            pageReq.setPageNum(pageReq.getPageNum() + 1);
        } while (pageReq.getPageNum() <= pkgPage.getTotalPages());
        log.info("cache package info finish!!!");
    }
}
